using System;
using System.Collections.Generic;
using System.Text;

using PostSharp.Laos;
using EntlibAOP.Diagnostic.Logging;
using System.Diagnostics;
using System.Reflection;

namespace EntlibAOP.Diagnostic.Tracing
{
    [Serializable]
    public class PerformanceTrackerAttribute : OnMethodInvocationAspect
    {
        private string methodName;
        private string logMessage;
        private string[] category;
        /// <summary>
        /// Trace message extended properties
        /// </summary>
        private IDictionary<string, object> extProperties;
        

        #region Properties
        /// <summary>
        /// Trace message
        /// </summary>
        public string Message
        {
            get { return logMessage; }
            set { logMessage = value; }
        }
        /// <summary>
        /// Trace message categories
        /// </summary>
        public string[] Categories
        {
            get { return category; }
            set { category = value; }
        }
        /// <summary>
        /// Trace message extended properties
        /// </summary>
        public IDictionary<string, object> ExtendedProperties
        {
            get { return extProperties; }
            set { extProperties = value; }
        }
        
        #endregion
        
        #region Overloaded Methods
        public override void CompileTimeInitialize(MethodBase method)
        {
            base.CompileTimeInitialize(method);
            methodName = method.DeclaringType.Name + "." + method.Name;
        }
        

        public override void OnInvocation(MethodInvocationEventArgs eventArgs)
        {
            Stopwatch stopWatch = Stopwatch.StartNew();
            try
            {
                eventArgs.ReturnValue = eventArgs.Delegate.DynamicInvoke(eventArgs.GetArgumentArray());
            }
            finally
            {
                stopWatch.Stop();
                // Get the elapsed time as a TimeSpan value.
                TimeSpan ts = stopWatch.Elapsed;
                // Format and display the TimeSpan value.
                string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                    ts.Hours, ts.Minutes, ts.Seconds,
                    ts.Milliseconds / 10);

                //Logging the elapsed time
                Logger.WriteInformation(this.category, this.extProperties, "Total time of execution of " + this.methodName + ":" + elapsedTime);
            }
        }
        #endregion

    }
}
